﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using Hxsoft.AppV1;

namespace Hxsoft.AppV1.Module
{
	public partial class Module : ICreator { }




	/// <summary>
	/// Modules 类。
	/// </summary>
	public static partial class Modules
	{
		public const string INFO_TYPE = "Module";



		#region GetIdentifier
		public static int? GetIdentifier(int? siteId, string moduleCode)
		{
			if (!siteId.HasValue) return null;
			return GetIdentifier(siteId.Value, moduleCode);
		}

		/// <summary>
		/// 根据指定的信息获取类别标识。
		/// </summary>
		/// <param name="o">类别的集合。</param>
		/// <param name="siteId">所属站点标识。</param>
		/// <param name="moduleCode">类别代码。</param>
		/// <returns>指定的类别的标识。</returns>
		public static int? GetIdentifier(int siteId, string moduleCode)
		{
			string key = siteId + "-" + moduleCode;
			Dictionary<string, int?> ids = GenericCacheContainer.Instance.ModuleIdByCodeDictionary;
			if (ids.ContainsKey(key))
				return ids[key];

			lock (ids)
			{
				if (!ids.ContainsKey(key))
				{
					GenericModuleDataContext dc = new GenericModuleDataContext();
					dc.ObjectTrackingEnabled = false;
					int? value = dc.Modules.GetIdentifier(siteId, moduleCode);
					try
					{
						ids[key] = value;
					}
					catch (IndexOutOfRangeException err)
					{
						ids.Clear();
						ids[key] = value;
					}
				}
			}
			return ids[key];
		}

		/// <summary>
		/// 根据指定的信息获取类别标识。
		/// </summary>
		/// <param name="o">类别的集合。</param>
		/// <param name="siteId">所属站点标识。</param>
		/// <param name="classCode">类别代码。</param>
		/// <returns>指定的类别的标识。</returns>
		internal static int? GetIdentifier(this System.Data.Linq.Table<Module> o, int siteId, string moduleCode)
		{
			var q = from p in o
					where p.SiteId == siteId && p.ModuleCode == moduleCode
					select (int?)p.ModuleId;
			return q.SingleOrDefault();
		}
		#endregion



		#region GetSiteIdByModuleId
		public static int? GetSiteIdByModuleId(this System.Data.Linq.Table<Module> o, int moduleId)
		{
			var q = from p in o
					where p.ModuleId == moduleId
					select (int?)p.SiteId;
			return q.SingleOrDefault();
		}

		public static int? GetSiteIdByModuleId(int moduleId)
		{
			Dictionary<int, int?> siteIds = GenericCacheContainer.Instance.SiteIdByModuleIdDictionary;
			if (siteIds.ContainsKey(moduleId))
				return siteIds[moduleId];

			lock (siteIds)
			{
				if (!siteIds.ContainsKey(moduleId))
				{
					GenericModuleDataContext dc = new GenericModuleDataContext();
					dc.ObjectTrackingEnabled = false;
					int? value = dc.Modules.GetSiteIdByModuleId(moduleId);
					try
					{
						siteIds[moduleId] = value;
					}
					catch (IndexOutOfRangeException err)
					{
						siteIds.Clear();
						siteIds[moduleId] = value;
					}
				}
			}
			return siteIds[moduleId];
		}
		#endregion



		#region GetDescendantIdsByParentId
		public static int[] GetDescendantIdsByParentId(this System.Data.Linq.Table<Module> o, int parentId)
		{
			List<int> childIds = (from p in o where p.PModuleId == parentId select p.ModuleId).ToList();
			List<int> descendantIds = null;
			if (childIds != null && childIds.Count > 0)
			{
				descendantIds = new List<int>(childIds);
				foreach (int id in childIds)
				{
					int[] ids = GetDescendantIdsByParentId(o, id);
					if(ids != null && ids.Length > 0)
						descendantIds.AddRange(ids);
				}
			}

			if (descendantIds == null || descendantIds.Count == 0) return null;
			return descendantIds.ToArray();
		}

		public static int[] GetDescendantIdsByParentId(int parentId)
		{
			Dictionary<int, int[]> descendantIds = GenericCacheContainer.Instance.DescendantIdsByParentIdDictionary;
			if (descendantIds.ContainsKey(parentId))
				return descendantIds[parentId];

			lock (descendantIds)
			{
				if (!descendantIds.ContainsKey(parentId))
				{
					GenericModuleDataContext dc = new GenericModuleDataContext();
					dc.ObjectTrackingEnabled = false;
					int[] value = dc.Modules.GetDescendantIdsByParentId(parentId);
					try
					{
						descendantIds[parentId] = value;
					}
					catch (IndexOutOfRangeException err)
					{
						descendantIds.Clear();
						descendantIds[parentId] = value;
					}
				}
			}
			return descendantIds[parentId];
		}
		#endregion



		#region GetPathCodesById
		public static string[] GetPathCodesById(this System.Data.Linq.Table<Module> o, int id)
		{
			Module module = (from p in o where p.ModuleId == id select p).SingleOrDefault();
			List<string> paths = new List<string>();
			if(module.PModuleId.HasValue)
				paths.AddRange(GetPathCodesById(o, module.PModuleId.Value));
			paths.Add(module.ModuleCode);
			return paths.ToArray();
		}

		public static string[] GetPathCodesById(int id)
		{
			Dictionary<int, string[]> ancestorCodes = GenericCacheContainer.Instance.PathCodesByIdDictionary;
			if (ancestorCodes.ContainsKey(id))
				return ancestorCodes[id];

			lock (ancestorCodes)
			{
				if (!ancestorCodes.ContainsKey(id))
				{
					GenericModuleDataContext dc = new GenericModuleDataContext();
					dc.ObjectTrackingEnabled = false;
					string[] value = dc.Modules.GetPathCodesById(id);
					try
					{
						ancestorCodes[id] = value;
					}
					catch (IndexOutOfRangeException err)
					{
						ancestorCodes.Clear();
						ancestorCodes[id] = value;
					}
				}
			}
			return ancestorCodes[id];
		}
		#endregion



		#region GetCodeById
		public static string GetCodeById(this System.Data.Linq.Table<Module> o, int moduleId)
		{
			var q = from p in o
					where p.ModuleId == moduleId
					select p.ModuleCode;
			return q.SingleOrDefault();
		}

		public static string GetCodeById(int moduleId)
		{
			Dictionary<int, string> codes = GenericCacheContainer.Instance.ModuleCodeByIdDictionary;
			if (codes.ContainsKey(moduleId))
				return codes[moduleId];

			lock (codes)
			{
				if (!codes.ContainsKey(moduleId))
				{
					GenericModuleDataContext dc = new GenericModuleDataContext();
					dc.ObjectTrackingEnabled = false;
					string value = dc.Modules.GetCodeById(moduleId);
					try
					{
						codes[moduleId] = value;
					}
					catch (IndexOutOfRangeException err)
					{
						codes.Clear();
						codes[moduleId] = value;
					}
				}
			}
			return codes[moduleId];
		}
		#endregion



		#region GetTreeListById
		public static List<Module> GetTreeListById(this System.Data.Linq.Table<Module> o, int? siteId, int? moduleId)
		{
			List<Module> rModules = new List<Module>();
			List<Module> modules = GetChildren(siteId, moduleId);
			foreach (Module module in modules)
			{
				rModules.Add(module);
				rModules.AddRange(GetTreeListById(o, siteId, module.ModuleId));
			}
			return rModules;
		}

		public static List<Module> GetTreeListById(int? siteId, int? moduleId)
		{
			string key = siteId + "-" + moduleId;
			Dictionary<string, List<Module>> modules = GenericCacheContainer.Instance.ModuleTreeListByIdDictionary;
			if (modules.ContainsKey(key))
				return modules[key];

			lock (modules)
			{
				if (!modules.ContainsKey(key))
				{
					GenericModuleDataContext dc = new GenericModuleDataContext();
					dc.ObjectTrackingEnabled = false;
					List<Module> value = dc.Modules.GetTreeListById(siteId, moduleId);
					try
					{
						modules[key] = value;
					}
					catch (IndexOutOfRangeException err)
					{
						modules.Clear();
						modules[key] = value;
					}
				}
			}
			return modules[key];
		}
		#endregion



		#region GetNameById
		public static string GetNameById(this System.Data.Linq.Table<Module> o, int moduleId)
		{
			var q = from p in o
					where p.ModuleId == moduleId
					select p.ModuleName;
			return q.SingleOrDefault();
		}

		public static string GetNameById(int moduleId)
		{
			Dictionary<int, string> names = GenericCacheContainer.Instance.ModuleNameByIdDictionary;
			if (names.ContainsKey(moduleId))
				return names[moduleId];

			lock (names)
			{
				if (!names.ContainsKey(moduleId))
				{
					GenericModuleDataContext dc = new GenericModuleDataContext();
					dc.ObjectTrackingEnabled = false;
					string value = dc.Modules.GetNameById(moduleId);
					try
					{
						names[moduleId] = value;
					}
					catch (IndexOutOfRangeException err)
					{
						names.Clear();
						names[moduleId] = value;
					}
				}
			}
			return names[moduleId];
		}

		public static string GetNameById(int siteId, string moduleCode)
		{
			int? moduleId = GetIdentifier(siteId, moduleCode);
			if (!moduleId.HasValue) return null;
			return GetNameById(moduleId.Value);
		}

		public static string GetNameById(int? siteId, string moduleCode)
		{
			if (!siteId.HasValue) return null;
			return GetNameById(siteId.Value, moduleCode);
		}
		#endregion



		#region GetItem
		/// <summary>
		/// 根据标识获取指定的模块。
		/// </summary>
		/// <param name="o">模块集合。</param>
		/// <param name="moduleId">获取的模块标识 ModuleId。</param>
		/// <returns>获取的信息项。</returns>
		public static Module GetItem(this System.Data.Linq.Table<Module> o, int moduleId)
		{
			return o.SingleOrDefault(p => p.ModuleId == moduleId);
		}

		public static Module GetItem(int moduleId, bool trackObject)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = trackObject;
			return dc.Modules.GetItem(moduleId);
		}

		public static Module GetItem(int moduleId)
		{
			return GetItem(moduleId, false);
		}

		/// <summary>
		/// 根据标识获取指定的模块。
		/// </summary>
		/// <param name="o">模块集合。</param>
		/// <param name="moduleId">获取的模块标识 ModuleId。</param>
		/// <returns>获取的信息项。</returns>
		public static Module GetItem(this System.Data.Linq.Table<Module> o, int siteId, string moduleCode)
		{
			return o.SingleOrDefault(p => p.SiteId == siteId && p.ModuleCode == moduleCode);
		}

		public static Module GetItem(int siteId, string moduleCode, bool trackObject)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = trackObject;
			return dc.Modules.GetItem(siteId, moduleCode);
		}

		public static Module GetItem(int siteId, string moduleCode)
		{
			return GetItem(siteId, moduleCode, false);
		}
		#endregion



		#region GetChildren
		public static List<Module> GetRoots(this System.Data.Linq.Table<Module> o, int siteId)
		{
			return (from p in o where p.SiteId == siteId && p.PModuleId == null orderby p.CreationDate ascending select p).ToList();
		}

		public static List<Module> GetRoots(int siteId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.Modules.GetRoots(siteId);
		}



		public static List<Module> GetChildren(this System.Data.Linq.Table<Module> o, int siteId, int? pModuleId)
		{
			if (pModuleId.HasValue)
				return (from p in o where p.SiteId == siteId && p.PModuleId == pModuleId.Value orderby p.CreationDate ascending select p).ToList();
			else
				return (from p in o where p.SiteId == siteId && p.PModuleId == null orderby p.CreationDate ascending select p).ToList();
		}

		public static List<Module> GetChildren(int siteId, int? pModuleId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.Modules.GetChildren(siteId, pModuleId);
		}



		public static List<Module> GetChildren(this System.Data.Linq.Table<Module> o, int? pModuleId)
		{
			if(pModuleId.HasValue)
				return (from p in o where p.PModuleId == pModuleId.Value orderby p.CreationDate ascending select p).ToList();
			else
				return (from p in o where p.PModuleId == null orderby p.CreationDate ascending select p).ToList();
		}

		public static List<Module> GetChildren(int? pModuleId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.Modules.GetChildren(pModuleId);
		}

		public static List<Module> GetChildren(int? siteId, int? pModuleId)
		{
			if (siteId.HasValue)
				return GetChildren(siteId.Value, pModuleId);
			else
				return GetChildren(pModuleId);
		}

		public static List<Module> GetChildren(int siteId, string pModuleCode)
		{
			int? pModuleId = GetIdentifier(siteId, pModuleCode);
			if (pModuleId == null) return null;
			return GetChildren(pModuleId.Value);
		}
		#endregion



		#region GetRoot
		public static Module GetRoot(int moduleId)
		{
			Module module = Modules.GetItem(moduleId);
			if(module == null) return module;
			if (module.PModuleId.HasValue)
				return GetRoot(module.PModuleId.Value);
			else
				return module;
		}
		#endregion



		#region Exists
		/// <summary>
		/// 验证指定的模块是否已经存在。
		/// </summary>
		/// <param name="o">模块集合。</param>
		/// <param name="moduleId">验证的模块标识 ModuleId。</param>
		/// <returns>布尔值表示指定的模块是否已经存在。</returns>
		public static bool Exists(this System.Data.Linq.Table<Module> o, int moduleId)
		{
			return o.Any(p => p.ModuleId == moduleId);
		}

		public static bool Exists(int moduleId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.Modules.Exists(moduleId);
		}

		/// <summary>
		/// 验证指定的模块是否已经存在。
		/// </summary>
		/// <param name="o">模块集合。</param>
		/// <param name="moduleId">验证的模块标识 ModuleId。</param>
		/// <returns>布尔值表示指定的模块是否已经存在。</returns>
		public static bool Exists(this System.Data.Linq.Table<Module> o, int siteId, string moduleCode)
		{
			return o.Any(p => p.SiteId == siteId && p.ModuleCode == moduleCode);
		}

		public static bool Exists(int siteId, string moduleCode)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.Modules.Exists(siteId, moduleCode);
		}
		#endregion
	}



	/// <summary>
	/// Modules 类操作部分。
	/// </summary>
	public static partial class Modules
	{
		#region Insert
		/// <summary>
		/// 添加模块。
		/// </summary>
		/// <param name="insertedModule">添加的模块。</param>
		/// <param name="check">权限验证方法。</param>
		/// <returns>添加的模块。</returns>
		private static Module Insert(Module insertedModule, RightCheckMethod<GenericModuleDataContext, Module> check)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Module module = insertedModule.ToNewEntity<Module>();
			module.CreatorId = Users.CurrentUserId;
			module.CreationDate = DateTime.Now;

			if(check != null) check(dc, module, true);	// 权限验证

			if (module.PModuleId != null)
			{
				Module pModule = dc.Modules.GetItem(module.PModuleId.Value);
				if (pModule == null)
					throw new ObjectNotExistsException(Res.Modules_NotExistsParent);
				pModule.ChildCount += 1;		// 上级节点的子节点数加1
			}
			dc.Modules.InsertOnSubmit(module);
			dc.SubmitChanges();

			// 注册权限
			RegisterModuleArticleReleasePermission(module);

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Insert, INFO_TYPE, module.ModuleId.ToString(), PermissionCode.Insert.ToString(), module.ModuleName);

			// 返回只读数据
			return insertedModule.FillByEntity(module);
		}



		/// <summary>
		/// 添加模块。
		/// </summary>
		/// <param name="insertedModule">添加的模块。</param>
		/// <returns>添加的模块。</returns>
		internal static Module _Insert(Module insertedModule)
		{
			return Insert(insertedModule, null);
		}



		/// <summary>
		/// 添加模块。
		/// </summary>
		/// <param name="insertedModule">添加的模块。</param>
		/// <returns>添加的模块。</returns>
		public static Module Insert(Module insertedModule)
		{
			insertedModule.IsHidden = false;
			return Insert(insertedModule, (GenericModuleDataContext dc, Module module, bool triggerException) => GetInsertRight(dc, module, triggerException));
		}
		#endregion



		#region Update
		private static readonly HashSet<string> _updatedColumns = typeof(Module).GetEntityColumnNames(new string[] {
				"ModuleName",
				"Memo","Keyword","Describe"
			}, true);

		/// <summary>
		/// 修改模块。
		/// </summary>
		/// <param name="updatedModule">修改的模块。</param>
		/// <returns>修改的模块。</returns>
		private static Module Update(Module updatedModule, RightCheckMethod<GenericModuleDataContext, Module> check)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Module module = dc.Modules.GetItem(updatedModule.ModuleId);
			if (module == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			if (check != null) check(dc, module, true);	// 权限验证

			module.FillByEntity(updatedModule, _updatedColumns);

			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 注册权限
			RegisterModuleArticleReleasePermission(module);

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Update, INFO_TYPE, module.ModuleId.ToString(), PermissionCode.Update.ToString(), module.ModuleName);

			// 返回只读数据
			return updatedModule.FillByEntity(module);
		}



		/// <summary>
		/// 修改模块。
		/// </summary>
		/// <param name="updatedModule">修改的模块。</param>
		/// <returns>修改的模块。</returns>
		internal static Module _Update(Module updatedModule)
		{
			return Update(updatedModule, null);
		}



		/// <summary>
		/// 修改模块。
		/// </summary>
		/// <param name="updatedModule">修改的模块。</param>
		/// <returns>修改的模块。</returns>
		public static Module Update(Module updatedModule)
		{
			return Update(updatedModule, (GenericModuleDataContext dc, Module module, bool triggerException) => GetUpdateRight(dc, module, triggerException));
		}
		#endregion



		#region Delete
		/// <summary>
		/// 删除模块。
		/// </summary>
		/// <param name="moduleId">删除的模块标识 ModuleId。</param>
		private static void Delete(int moduleId, RightCheckMethod<GenericModuleDataContext, Module> check)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Module module = dc.Modules.GetItem(moduleId);
			if (module == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			if (check != null) check(dc, module, true);	// 权限验证

			Delete(dc, module);

			dc.SubmitChanges();

			// 记录日志
			Logs.Insert(dc, ResourceId, (int)PermissionCode.Delete, INFO_TYPE, module.ModuleId.ToString(), PermissionCode.Delete.ToString(), module.ModuleName);
		}



		/// <summary>
		/// 删除模块。
		/// </summary>
		/// <param name="moduleId">删除的模块标识 ModuleId。</param>
		internal static void _Delete(int moduleId)
		{
			Delete(moduleId, null);
		}



		/// <summary>
		/// 删除模块。
		/// </summary>
		/// <param name="moduleId">删除的模块标识 ModuleId。</param>
		public static void Delete(int moduleId)
		{
			Delete(moduleId, (GenericModuleDataContext dc, Module module, bool triggerException) => GetDeleteRight(dc, module, triggerException));
		}



		#region internal Delete
		internal static void Delete(GenericModuleDataContext dc, Module module)
		{
			if (module.Parent != null)
				module.Parent.ChildCount -= 1;		// 上级节点数减1
			Modules.DeleteByParent(dc, module);	// 删除关联数据
			ModuleArticles.DeleteByParent(dc, module);	// 删除关联数据
			dc.Modules.DeleteOnSubmit(module);

			// 删除权限注册
			Resource resource = dc.Resources.GetItem(ArticleReleaseResourceCategoryId, module.SiteId, GetArticleReleaseResourceCode(module.ModuleId));
			if (resource != null)
				Resources.Delete(dc, resource);
		}

		internal static void DeleteByParent(GenericModuleDataContext dc, Module parent)
		{
			IEnumerable<Module> e = parent.Children.AsEnumerable();
			foreach (Module i in e)
				Delete(dc, i);
		}

		internal static void DeleteByParent(GenericModuleDataContext dc, Site parent)
		{
			IEnumerable<Module> e = parent.Modules.AsEnumerable();
			foreach (Module i in e)
				Delete(dc, i);
		}
		#endregion
		#endregion
	}



	/// <summary>
	/// Modules 类对应操作权限部分。（受限站点资源。）
	/// </summary>
	public static partial class Modules
	{
		#region GetInsertRight
		/// <summary>
		/// 获取当前用户是否有添加模块的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="module">添加的模块对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有添加模块的权限。</returns>
		public static bool GetInsertRight(GenericModuleDataContext dc, Module module, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)PermissionCode.Insert;
			bool b = dc.AccessController.GetUserIsHasPermission<Module>(userName, module, ResourceId, permissionCode, module.SiteId);

			if (triggerException && !b)
				throw new PermissionException(userName, module, ResourceId, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有添加模块的权限。
		/// </summary>
		/// <param name="module">添加的模块对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有添加模块的权限。</returns>
		public static bool GetInsertRight(Module module, bool triggerException)
		{
			return GetInsertRight(new GenericModuleDataContext(), module, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有添加模块的权限。
		/// </summary>
		/// <param name="module">添加的模块对象。</param>
		/// <returns>布尔值表示当前用户是否有添加模块的权限。</returns>
		public static bool GetInsertRight(Module module)
		{
			return GetInsertRight(module, false);
		}
		#endregion



		#region GetUpdateRight
		/// <summary>
		/// 获取当前用户是否有更新模块的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="module">更新的模块对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有更新模块的权限。</returns>
		public static bool GetUpdateRight(GenericModuleDataContext dc, Module module, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)PermissionCode.Update;
			bool b = dc.AccessController.GetUserIsHasPermission<Module>(userName, module, ResourceId, permissionCode, module.SiteId);

			if (triggerException && !b)
				throw new PermissionException(userName, module, ResourceId, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有更新模块的权限。
		/// </summary>
		/// <param name="module">更新的模块对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有更新模块的权限。</returns>
		public static bool GetUpdateRight(Module module, bool triggerException)
		{
			return GetUpdateRight(new GenericModuleDataContext(), module, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有更新模块的权限。
		/// </summary>
		/// <param name="module">更新的模块对象。</param>
		/// <returns>布尔值表示当前用户是否有更新模块的权限。</returns>
		public static bool GetUpdateRight(Module module)
		{
			return GetUpdateRight(module, false);
		}
		#endregion



		#region GetDeleteRight
		/// <summary>
		/// 获取当前用户是否有删除模块的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="module">删除的模块对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有删除模块的权限。</returns>
		public static bool GetDeleteRight(GenericModuleDataContext dc, Module module, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)PermissionCode.Delete;
			bool b = dc.AccessController.GetUserIsHasPermission<Module>(userName, module, ResourceId, permissionCode, module.SiteId);

			if (triggerException && !b)
				throw new PermissionException(userName, module, ResourceId, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有删除模块的权限。
		/// </summary>
		/// <param name="module">删除的模块对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有删除模块的权限。</returns>
		public static bool GetDeleteRight(Module module, bool triggerException)
		{
			return GetDeleteRight(new GenericModuleDataContext(), module, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有删除模块的权限。
		/// </summary>
		/// <param name="module">删除的模块对象。</param>
		/// <returns>布尔值表示当前用户是否有删除模块的权限。</returns>
		public static bool GetDeleteRight(Module module)
		{
			return GetDeleteRight(module, false);
		}
		#endregion
	}




	/// <summary>
	/// Modules 类后台管理部分。
	/// </summary>
	public static partial class Modules
	{
		public static bool GetManageListRight()
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			return dc.AccessController.GetUserIsHasPermission<object>(Users.CurrentUserName, null, Modules.ResourceId, (int)Modules.PermissionCode.Update, App.Context.CurrentSiteId);
		}

		public static bool GetManageListRight(int? siteId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			return dc.AccessController.GetUserIsHasPermission<object>(Users.CurrentUserName, null, Modules.ResourceId, (int)Modules.PermissionCode.Update, siteId);
		}



		public static PaginationInfo<List<Module>> GetPaginationManageList(int? siteId, int? pModuleId, string keyword, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = from p in dc.Modules
					where p.IsHidden == false
					select p;

			if (siteId.HasValue)
				q = q.Where(p => p.SiteId == siteId.Value);
			if(pModuleId.HasValue)
				q = q.Where(p => p.PModuleId == pModuleId.Value);
			else
				q = q.Where(p => p.PModuleId == null);
			if (!string.IsNullOrEmpty(keyword))
				q = q.Where(p => p.ModuleName.Contains(keyword));

			PaginationInfo<List<Module>> pageInfo = new PaginationInfo<List<Module>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}
	}
}